package com.cincc.cinccimdemo.widget;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.Editable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.cincc.cinccimdemo.R;
import com.cincc.cinccimdemo.common.KeyBoardUtils;
import com.cincc.cinccimdemo.common.MyUtils;
import com.cincc.cinccimdemo.common.ServiceUtil;
import com.cincc.cinccimdemo.common.TranslationUtils;
import com.cincc.cinccimdemo.common.record.VoiceInfo;
import com.cincc.cinccimdemo.model.ConversationInfo;
import com.cincc.cinccimdemo.model.MessageInfo;
import com.cincc.cinccimdemo.model.MessageInfoUI;
import com.cincc.cinccimdemo.ui.conversation.mention.MentionGroupMemberActivity;
import com.cincc.cinccimdemo.ui.conversation.mention.MentionSpan;
import com.cincc.cinccimdemo.viewmodel.ConversationViewModel;
import com.cincc.im.callback.ImCallback;
import com.cincc.im.core.IMSipPhoneCtrl;
import com.cincc.im.model.ImMessageInfo;
import com.cincc.im.model.ImResponse;
import com.cincc.im.model.dbmodel.GroupMemberInfo;
import com.cincc.im.model.enums.ImSendType;
import com.cincc.im.model.enums.SendStatus;

import java.util.ArrayList;
import java.util.List;

public class ConversationInputLayout extends FrameLayout implements View.OnClickListener {

    private static final String TAG = "ConversationInputLayout";
    public static final int REQUEST_PICK_MENTION_CONTACT = 1009;

    private EditText editText;
    private Button btnSend;
    private ImageView addImage;
    private ImageView audioImage;
    private ImageView emojiImage;
    private AudioTextView audioTextView;
    private RelativeLayout refRelativeLayout;
    private EditText refEditText;
    private ImageButton clearRefImageButton;

    private Activity mContext;
    private ConversationViewModel conversationViewModel;
    private TranslationUtils translationUtils;
    private ConversationMoreLayout conversationMoreLayout;
    ConversationInfo conversationInfo;

    public ConversationInputLayout(@NonNull Context mContext) {
        super(mContext);
        init(mContext);
    }

    public ConversationInputLayout(@NonNull Context mContext, @Nullable AttributeSet attrs) {
        super(mContext, attrs);
        init(mContext);
    }

    public ConversationInputLayout(@NonNull Context mContext, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(mContext, attrs, defStyleAttr);
        init(mContext);
    }

    @SuppressLint("ClickableViewAccessibility")
    private void init(Context context) {
        this.mContext = (Activity) context;
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.conversation_input_layout, this);
        audioTextView = findViewById(R.id.tv_audio);

        editText = findViewById(R.id.ed_edit);
        btnSend = findViewById(R.id.btn_send);
        addImage = findViewById(R.id.iv_add);
        audioImage = findViewById(R.id.iv_audio);
        emojiImage = findViewById(R.id.iv_emoji);
        refRelativeLayout = findViewById(R.id.refRelativeLayout);
        refEditText = findViewById(R.id.refEditText);
        clearRefImageButton = findViewById(R.id.clearRefImageButton);
        btnSend.setOnClickListener(this);
        audioImage.setOnClickListener(v -> {
            applyPermission();
        });
        clearRefImageButton.setOnClickListener(v -> {
            refRelativeLayout.setVisibility(GONE);
            quoteMessage = null;
        });

        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                onInputTextChanged(s, start, before, count);
            }

            @Override
            public void afterTextChanged(Editable s) {
                btnSend.setVisibility(s.toString().trim().isEmpty() ? View.GONE : View.VISIBLE);
                IMSipPhoneCtrl.getInstance().updateDraft(conversationInfo.imSendType, conversationInfo.targetId, s.toString());
            }
        });
        addImage.setOnClickListener(v -> changeMoreLayout(false));
        emojiImage.setOnClickListener(v -> changeMoreLayout(true));
        editText.setOnTouchListener((View v, MotionEvent event) -> {
            emojiImage.setImageResource(R.mipmap.ic_emoji);
            if (event.getAction() == MotionEvent.ACTION_UP && translationUtils.isBottomLayoutShown()) {
                translationUtils.hideBottomLayout();
            }
            return false;
        });
    }

    public EditText getExitText() {
        return editText;
    }


    public void setParams(ConversationViewModel conversationViewModel, TranslationUtils translationUtils, VoiceArcView voiceArcView, ConversationMoreLayout conversationMoreLayout, ConversationInfo conversationInfo) {
        this.conversationViewModel = conversationViewModel;
        this.conversationInfo = conversationInfo;
        this.translationUtils = translationUtils;
        this.conversationMoreLayout = conversationMoreLayout;
        audioTextView.setAudioCallback(voiceArcView, (code, info) -> {
            if (code == 1) {
                sendVoice(info);
            } else {
                MyUtils.showWarn(mContext, R.mipmap.conversation_audio_warn, R.string.dialog_audio_warn);
            }
        });
        editText.setText(conversationInfo.draft);
    }

    public void clickRecycler() {
        editText.clearFocus();
        conversationMoreLayout.hideContent();
        KeyBoardUtils.closeKeyBoard(mContext, editText);
        translationUtils.hideBottomLayout();
        emojiImage.setImageResource(R.mipmap.ic_emoji);
    }

    private void changeMoreLayout(Boolean isEmoji) {
        editText.clearFocus();
        Boolean isKeyboardShowing = conversationViewModel.keyboardShowingLiveData().getValue();

        int emojiVisibility = conversationMoreLayout.emojiIsShow();
        int moreVisibility = conversationMoreLayout.moreIsShow();

        if (isEmoji) {
            if (Boolean.TRUE.equals(isKeyboardShowing)) {
                conversationMoreLayout.setContent(true);
                KeyBoardUtils.closeKeyBoard(mContext, editText);
                editText.postDelayed(() -> translationUtils.showMoreLayout(), 100);
                emojiImage.setImageResource(R.mipmap.ic_keyboard);
            } else {
                if (emojiVisibility == VISIBLE) {
                    emojiImage.setImageResource(R.mipmap.ic_emoji);
                    translationUtils.hideBottomLayout();
                    KeyBoardUtils.openKeyBoard(mContext, editText);
                } else {
                    emojiImage.setImageResource(R.mipmap.ic_keyboard);
                    conversationMoreLayout.setContent(true);
                    if (!translationUtils.isMoreLayoutShown()) {
                        editText.postDelayed(() -> translationUtils.showMoreLayout(), 100);
                    }
                }
            }
        } else {
            emojiImage.setImageResource(R.mipmap.ic_emoji);
            if (Boolean.TRUE.equals(isKeyboardShowing)) {
                conversationMoreLayout.setContent(false);
                KeyBoardUtils.closeKeyBoard(mContext, editText);
                editText.postDelayed(() -> translationUtils.showMoreLayout(), 100);
                emojiImage.setImageResource(R.mipmap.ic_keyboard);
            } else {
                if (moreVisibility == VISIBLE) {
                    translationUtils.hideBottomLayout();
                    KeyBoardUtils.openKeyBoard(mContext, editText);
                } else {
                    conversationMoreLayout.setContent(false);
                    translationUtils.showMoreLayout();
                }
            }
        }
    }

    /**
     * 显示输入框
     */
    private void showInput() {
        editText.post(() -> {
            editText.requestFocus();
            ServiceUtil.getInputMethodManager(editText.getContext()).showSoftInput(editText, 0);
        });
        Boolean isKeyboardShowing = conversationViewModel.keyboardShowingLiveData().getValue();
        audioImage.setImageResource(R.mipmap.ic_audio);
        if (Boolean.FALSE.equals(isKeyboardShowing)) KeyBoardUtils.openKeyBoard(mContext, editText);
        if (translationUtils.isButtomLayoutShown()) translationUtils.hideBottomLayout();
        editText.setVisibility(View.VISIBLE);
        audioTextView.setVisibility(View.INVISIBLE);
    }

    /**
     * 显示语音输入框
     */
    private void showAudio() {
        ServiceUtil.getInputMethodManager(editText.getContext()).hideSoftInputFromWindow(editText.getWindowToken(), 0);
        audioImage.setImageResource(R.mipmap.ic_keyboard);
        Boolean isKeyboardShowing = conversationViewModel.keyboardShowingLiveData().getValue();
        if (Boolean.TRUE.equals(isKeyboardShowing)) KeyBoardUtils.closeKeyBoard(mContext, editText);
        if (translationUtils.isButtomLayoutShown()) translationUtils.hideBottomLayout();
        editText.setVisibility(View.INVISIBLE);
        audioTextView.setVisibility(View.VISIBLE);
    }


    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_send) {
            String text = editText.getText().toString();
            sendText(text);
            quoteMessage = null;
            refRelativeLayout.setVisibility(GONE);
        }
    }

    int REQUEST_CODE_AUDIO_RECORD_CODE = 1208;

    private void applyPermission() {
        String[] permissions = new String[1];
        permissions[0] = Manifest.permission.RECORD_AUDIO;

        if (!checkPermission(permissions)) {
            mContext.requestPermissions(permissions, REQUEST_CODE_AUDIO_RECORD_CODE);
        } else {
            if (editText.getVisibility() == VISIBLE) {
                showAudio();
            } else {
                showInput();
            }
        }
    }

    private void sendText(String content) {
        String quoteId = quoteMessage == null ? "" : quoteMessage.getRemoteMsgId();
        String quoteContent = quoteMessage == null ? "" : MyUtils.getQuoteContent(quoteMessage);
        MessageInfo textMessage = MyUtils.getTextMessageInfo(content, conversationInfo.imSendType, quoteId, quoteContent);
        MessageInfoUI uiMessage = new MessageInfoUI(textMessage);
        conversationViewModel.conversationLiveData().postValue(uiMessage);

        if (ImSendType.isP2P(conversationInfo.imSendType)) {
            IMSipPhoneCtrl.getInstance().sendText(conversationInfo.targetId, content, "", quoteId, quoteContent, new ImCallback() {
                @Override
                public void callback(ImResponse imResponse) {
                    if (imResponse.getCode() == 0) {
                        ImMessageInfo imMessageInfo = (ImMessageInfo) imResponse.getData();
                        uiMessage.setRemoteMsgId(imMessageInfo.msgId);
                    }
                    uiMessage.setMessageStatus(imResponse.getCode() == 0 ? SendStatus.SEND_SUCCESS : SendStatus.SEND_FAILED);
                    conversationViewModel.updateConversationLiveData().postValue(uiMessage);
                }
            });
        } else {
            MentionSpan[] mentions = editText.getText().getSpans(0, content.length(), MentionSpan.class);
            List<String> list = new ArrayList<>();
            boolean isMentionAll = false;
            if (mentions != null && mentions.length > 0) {
                for (MentionSpan span : mentions) {
                    if (!list.contains(span.getUid())) {
                        list.add(span.getUid());
                    }
                    // mentionAll
                    if (span.isMentionAll()) {
                        isMentionAll = true;
                        break;
                    }
                }
            }
            if (isMentionAll) {
                list.clear();
                list.add("@all");
            }
            IMSipPhoneCtrl.getInstance().sendGroupText(conversationInfo.targetId, content, list, "", quoteId, quoteContent, new ImCallback() {
                @Override
                public void callback(ImResponse imResponse) {
                    if (imResponse.getCode() == 0) {
                        ImMessageInfo imMessageInfo = (ImMessageInfo) imResponse.getData();
                        uiMessage.setRemoteMsgId(imMessageInfo.msgId);
                    }
                    uiMessage.setMessageStatus(imResponse.getCode() == 0 ? SendStatus.SEND_SUCCESS : SendStatus.SEND_FAILED);
                    conversationViewModel.updateConversationLiveData().postValue(uiMessage);
                }
            });
        }
        editText.setText("");
        IMSipPhoneCtrl.getInstance().updateDraft(conversationInfo.imSendType, conversationInfo.targetId, "");
    }

    private void sendVoice(VoiceInfo audioInfo) {
        MessageInfo textMessage = MyUtils.getVoiceMessageInfo(audioInfo, conversationInfo.imSendType);
        MessageInfoUI uiMessage = new MessageInfoUI(textMessage);
        conversationViewModel.conversationLiveData().postValue(uiMessage);
        IMSipPhoneCtrl.getInstance().sendVoice(conversationInfo.imSendType, conversationInfo.targetId, audioInfo.getPath(), audioInfo.getDuration(), "", new ImCallback() {
            @Override
            public void callback(ImResponse imResponse) {
                if (imResponse.getCode() == 0) {
                    ImMessageInfo imMessageInfo = (ImMessageInfo) imResponse.getData();
                    uiMessage.setRemoteMsgId(imMessageInfo.msgId);
                }
                uiMessage.setMessageStatus(imResponse.getCode() == 0 ? SendStatus.SEND_SUCCESS : SendStatus.SEND_FAILED);
                conversationViewModel.updateConversationLiveData().postValue(uiMessage);
            }
        });
    }

    public boolean checkPermission(String[] permissions) {
        boolean granted = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for (String permission : permissions) {
                granted = mContext.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
                if (!granted) {
                    break;
                }
            }
        }
        return granted;
    }

    void onInputTextChanged(CharSequence s, int start, int before, int count) {
        if (mContext.getCurrentFocus() == editText) {
            if (conversationInfo.imSendType == ImSendType.IM_GROUP_MESSAGE) {
                if (before == 0 && count == 1 && s.charAt(start) == '@') {
                    MentionGroupMemberActivity.startMentionActivity(mContext, conversationInfo.targetId);
                }
                // delete
                if (before == 1 && count == 0) {
                    Editable text = editText.getText();
                    MentionSpan[] spans = text.getSpans(0, text.length(), MentionSpan.class);
                    if (spans != null) {
                        for (MentionSpan span : spans) {
                            if (text.getSpanEnd(span) == start && text.getSpanFlags(span) == Spanned.SPAN_INCLUSIVE_EXCLUSIVE) {
                                text.delete(text.getSpanStart(span), text.getSpanEnd(span));
                                text.removeSpan(span);
                                break;
                            } else if (start >= text.getSpanStart(span) && start < text.getSpanEnd(span)) {
                                text.removeSpan(span);
                                break;
                            }
                        }
                    }
                }

                // insert
                if (before == 0 && count > 0) {
                    Editable text = editText.getText();
                    MentionSpan[] spans = text.getSpans(0, text.length(), MentionSpan.class);
                    if (spans != null) {
                        for (MentionSpan span : spans) {
                            if (start >= text.getSpanStart(span) && start < text.getSpanEnd(span)) {
                                text.removeSpan(span);
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (requestCode == REQUEST_PICK_MENTION_CONTACT && data != null) {
            boolean isMentionAll = data.getBooleanExtra("mentionAll", false);
            SpannableString spannableString;
            if (isMentionAll) {
                spannableString = mentionAllSpannable();
            } else {
                String userId = data.getStringExtra("userId");
                GroupMemberInfo groupMemberInfo = IMSipPhoneCtrl.getInstance().getGroupMemberInfo(conversationInfo.targetId, userId);
                spannableString = mentionSpannable(groupMemberInfo);
            }
            int position = editText.getSelectionEnd();
            position = position > 0 ? position - 1 : 0;
            editText.getEditableText().replace(position, position + 1, spannableString);
        }
    }

    private SpannableString mentionAllSpannable() {
        String text = "@所有人 ";
        SpannableString spannableString = new SpannableString(text);
        spannableString.setSpan(new MentionSpan(true), 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        return spannableString;
    }

    private SpannableString mentionSpannable(GroupMemberInfo userInfo) {
        String text = "@" + MyUtils.getGroupMemberDisplayName(userInfo) + " ";
        SpannableString spannableString = new SpannableString(text);
        spannableString.setSpan(new MentionSpan(userInfo.memberId), 0, spannableString.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        return spannableString;
    }

    MessageInfoUI quoteMessage;

    public void quoteMessage(MessageInfoUI uiMessage) {
        quoteMessage = uiMessage;
        refRelativeLayout.setVisibility(View.VISIBLE);
        String data = MyUtils.getQuoteInfo(uiMessage);
        refEditText.setText(data);
    }
}
